package myJs

import myJs.Implicits._
import myJs.myPkg._
import myJs.myPkg.highcharts._
import myJs.myPkg.jquery._
import myJs.tool.Tool
import org.scalajs.dom.ext.Ajax
import org.scalajs.dom.{Element, Event, document}

import scala.concurrent.ExecutionContext.Implicits.global
import scala.scalajs.js
import scala.scalajs.js.Dynamic.{global => g}
import scala.scalajs.js.JSON
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}
import scala.scalajs.js.JSConverters._
import myJs.Implicits._

import scala.collection.immutable.SeqMap
import scalatags.Text.all._
import myJs.myPkg.bootstrap.Bootstrap.default._
import shared.VarTool

import scala.concurrent.Future

/** Created by yz on 11/5/2020
  */
@JSExportTopLevel("GeoMap")
object GeoMap {

  val tableId = "table"
  var tableRs: JArJDJAn = _

  @JSExport("init")
  def init = {
    initTable
    Browse.refreshSelect2("")
    refreshCountryInfo
    registerEvent
  }

  def tableFilterEvent = {
    Tool.clickHide

    $(document.body).on(
      "click",
      ".myOperate",
      "",
      (y: Element) => {
        Browse.filterContentShow(y)
      }
    )
    $(document.body).on(
      "click",
      ".mySortLi",
      "",
      (y: Element) => {
        Tool.execSort(
          y,
          "",
          () => {
            refreshTable()
          }
        )
      }
    )
    $(document.body).on(
      "click",
      ".myConfirm",
      "",
      (y: Element) => {
        Tool.confirmFilter(
          y,
          "",
          () => {
            refreshTable()
          }
        )
      }
    )
    $(document.body).on(
      "click",
      ".myHide",
      "",
      (y: Element) => {
        Tool.hideFilterContent(y)
      }
    )
    $(document.body).on(
      "click",
      s".myRemove",
      "",
      (y: Element) => {
        Tool.removeCondition(
          y,
          "",
          () => {
            refreshTable()
          }
        )
      }
    )
    $(document.body).on(
      "click",
      s".myRemoveSort",
      "",
      (y: Element) => {
        Tool.removeSort(
          y,
          "",
          () => {
            refreshTable()
          }
        )
      }
    )
  }

  def registerEvent = {
    tableFilterEvent
  }

  def expStyle(columnName: String): js.Function = (v: js.Any, row: js.Dictionary[Any]) =>
    columnName match {
      case _ => v
    }

  def initTable = {
    val map = VarTool.browseMap
    val allDatas = Browse.initFilterContent("", map)
    val columnNames = map.keyList
    val columns = columnNames.map { columnName =>
      val title = map.getOrElse(columnName, columnName)
      val fmt = Browse.tbFmt(columnName)
      val style = expStyle(columnName)
      val basicOptions = ColumnOptions.field(columnName).title(title).sortable(true).formatter(fmt).cellStyle(style)
      columnName match {
        case x if allDatas.map(_.fieldName).contains(x) => basicOptions.sortable(false).operateable(true)
        case "level" => basicOptions.`class`("myImgTd")
        case _ => basicOptions
      }
    }
    val options = TableOptions
      .columns(columns.toJSArray)
      .searchOnButton(false)
      .filterControl(false)
      .idField("id")
      .parentIdField("pId")
      .treeShowField("fileName")
      .treeEnable(true)
      .rootParentId("0")
      .search(false)
    $(s"#${tableId}").bootstrapTable(options)
    Tool.dateInit
    Tool.refreshCheckboxView(map.tail)

    map.keyList.drop(8).foreach { x =>
      $("#table").bootstrapTable("hideColumn", x)
      $(s"input:checkbox[value='${x}']").attr("checked", false)
    }

  }

  def refreshCountryInfo = {
    val url = g.jsRoutes.controllers.MapController.getCountryInfo().url.toString
    Ajax.get(url = s"${url.noCache}", headers = Map("Content-Type" -> "application/json")).map { xhr =>
      val rs = xhr.responseText.toJArJDJAn
      val datas = rs.map { dict =>
        MapData.name(dict.myGet("key")).value(dict.myGetInt("num"))
      }
      val config = HighchartsConfig
        .title(Title.text(" "))
        .subtitle(Title.text(""))
        .chart(Chart.map("custom/world"))
        .credits(Credits.enabled(false))
        .mapNavigation(
          MapNavigation.enabled(true).enableMouseWheelZoom(false).buttonOptions(ButtonOptions.verticalAlign("bottom"))
        )
        .series(
          js.Array(
            Series
              .`type`("map")
              .data(datas)
              .joinBy("name")
              .name("Data")
              .allowPointSelect(true)
              .cursor("pointer")
              .states(
                States
                  .hover(Hover.color("#a4edba"))
                  .select(Select.color("orange").borderColor("black").dashStyle("shortdot"))
              )
              .dataLabels(DataLabels.enabled(false).format("{point.name}"))
              .point(Point.events(Events.click((e: Event) => {
                val eachSeriesEvent = e.asInstanceOf[EachSeriesEvent]
                refreshTable(eachSeriesEvent.point.name)
              })))
          )
        )
        .colorAxis(
          ColorAxis
            .min(0)
            .stops(
              js.Array(
                (0, "#EFEFFF"),
                (0.5, Highcharts.getOptions().colors(0)),
                (1, new HighchartsColor(Highcharts.getOptions().colors(0)).brighten(-0.5).get())
              )
            )
        )
      $("#worldmap").highcharts("Map", config)
    }
  }

  def refreshTable(f: () => js.Any = () => ()) = {
    val queryMap = Tool.getFrontQueryMap("")
    println(queryMap)
    val data = tableRs.toMyJDS
    val sortData = Browse.sortExec(data, queryMap)

    def loopFilter(sortData: JArJDS) = {

      val filterColumns = queryMap.removedAll(List("sort", "order")).filter(_._2.map(_.trim).nonEmpty).keyList

      def loop(acc: JArJDS, elems: List[String]): JArJDS = {
        elems match {
          case Nil => acc
          case y :: ys =>
            val searchV = queryMap(y)
            val vs = searchV
            val trueSearchV = searchV.head
            val fieldName = y.split("\\.")(0)
            val name = y.split("\\.")(1)
            val jq = $(s"#${fieldName}Content").findInputByName(name)
            val curFilterData = if (jq.hasClass("myDatepicker")) {
              acc.filter { row =>
                val dbDate = row(fieldName)
                if (name == "startTime") {
                  Tool.timeBefore(vs.head, dbDate)
                } else {
                  Tool.timeAfter(vs.head, dbDate)
                }
              }
            } else if (jq.hasClass("select2MultiInput")) {
              acc.filter { row =>
                vs.exists(row(fieldName) == _)
              }
            } else if (jq.hasClass("rangeInput")) {
              acc.filter { row =>
                val dbDouble = row(fieldName).toDouble
                val v = vs.head
                if (v.isDouble) {
                  if (name == "min") {
                    dbDouble >= vs.head.toDouble
                  } else {
                    dbDouble <= vs.head.toDouble
                  }
                } else {
                  false
                }
              }
            } else {
              acc.filter { row =>
                row(fieldName).contains(vs.head)
              }
            }
            loop(curFilterData, ys)
        }
      }

      loop(sortData, filterColumns)
    }

    val filterData = loopFilter(sortData)
    $(s"#${tableId}").bootstrapTable("load", filterData)
    f()
  }

  def refreshTable(country: String): Future[JQuery] = {
    val index = layer.load(1, Tool.layerOptions.copy(shade=List("0.1", "#fff")))
    val url = g.jsRoutes.controllers.MapController.getProkaryoteByCountry().url.toString
    Ajax.get(url = s"${url}?country=${country}", headers = Map("Content-Type" -> "application/json")).map { xhr =>
      tableRs = xhr.responseText.toJArJDJAn
      refreshTable()
      layer.close(index)
      $("#tableResult").show()
      val target_top = $("#tableResult").offset().top
      $("html,body").animate(js.Dictionary("scrollTop" -> target_top), JQueryAnimationSettings.duration(800))
    }
  }

}
